/*
 This file 'FormHelper' is part of Firebird Integrated Solution 1.0

 Copyright (c) 2014 Lincong

 Contact:  
 Email: lincong1987@gmail.com

 QQ: 159257119

 See Usage at http://www.jplatformx.com/firebird

 Create date: 2014-06-19 15:46
 */

define(function (require, exports, module) {

	require("Firebird.ui.Component");

	var encoderLib = {
		base64: require("_fbCore_/js/base64/base64"),
		URI: {
			encode: encodeURI,
			decode: decodeURI
		},
		URIComponent: {
			encode: encodeURIComponent,
			decode: decodeURIComponent
		},
		// ECMAScript v3 已从标准中删除了 unescape() 函数，并反对使用它，
		// 因此应该用 decodeURI() 和 decodeURIComponent() 取而代之。
		escape: {
			encode: escape,
			decode: unescape
		},
		json: {
			encode: function (val) {
				var str = "";
				for (var i = 0; i < val.length; i++) {
					str += "\\u" + parseInt(val[i].charCodeAt(0), 10).toString(16);
				}
				return str;
			},
			decode: function (val) {
				val = val.split("\\u");
				var str = "";
				for (var i = 0; i < val.length; i++) {
					str += String.fromCharCode(parseInt(val[i], 16).toString(10));
				}
				return str;
			}
		},
		unicode: {
			encode: function (val) {
				return val.replace(/[^\u0000-\u00FF]/g, function ($0) {
					return escape($0).replace(/(%u)(\w{4})/gi, "&#x$2;")
				});
			},
			decode: function (val) {
				return unescape(val.replace(/&#x/g, '%u').replace(/;/g, ''));
			}
		},
		utf8: {
			encode: function (val) {
				return this.json.encode(val);
			},
			decode: function (val) {
				return this.json.decode(val);
			}
		},
		gb2312: {
			encode: function (val) {
				return val;
			},
			decode: function (val) {
				return val;
			}
		}
	};


	/**
	 * 表单助手，序列化、反序列化，设置值   Firebird.ui.FormHelper
	 * @class Firebird.ui.FormHelper
	 */
	Firebird.define("Firebird.ui.FormHelper", {
		extend: "Firebird.ui.Component",

		statics: {
			_uuid: 1,
			uuid: function () {
				return this._uuid++;
			},
			/**
			 * 属性适配器
			 * @param $component
			 * @returns {{}}
			 */
			attrs: function ($component) {
				return $.extend({}, {
					renderTo: $component.get(0),
					// 实例ID, 可以在 context 里直接获取， var ins = context.getInstance("name");
					instanceId: $component.attr("fb-instance") || $component.attr("name") || $component.attr("id") || ("formhelper_" + Firebird.ui.FormHelper.uuid()),

					url: $component.attr("fb-url"),

					nullValue: $component.attr("fb-nullValue") || "",

					validator: Firebird.ui.Component.eval($component.attr("fb-validator") || false),

					encode: $component.attr("fb-encode") || ""
				});
			}
		},

		config: {
			renderTo: null,
			instanceId: null,
			nullValue: "",
			url: null,
			validator: false,
			encode: null
		},

		_init: function () {
			var me = this;
			var genId = me.genId = Firebird.Model.getGenId();

			me.instance = $(me.getRenderTo()).data({
				instance: me,
				xtype: "formhelper"
			});

			if (!this.instance.attr("id")) {
				this.instance.attr("id", this.genId);
			}

			if (this.getValidator() == true) {

				//setTimeout(function () {
				me.setValidator(Firebird.create("Firebird.ui.FormValidator", {
					renderTo: me.instance,
					instanceId: "formvalidator_" + Firebird.ui.FormValidator.uuid()

					//onSuccess: null,
					//onError: null,
					//onValidation: null
				}));
				//}, 100);

			}

			$.each(this.encodeSupportArray, function (i, name) {
				me.registerEncoder(name, encoderLib[name] && encoderLib[name]["encode"], encoderLib[name] && encoderLib[name]["decode"]);
			});

		},

		render: function () {

		},

		registerEncoder: function (name, encoder, decoder) {
			this.encodeSupport[name] = {
				encode: encoder || function (val) {
					return val;
				},
				decode: decoder || function (val) {
					return val;
				}
			};
		},
		encodeSupportArray: ["md5", "base64", "URI", "URIComponent", "escape", "json", "utf8", "html"],
		encodeSupport: {},

		needEncode: function () {
			return $.inArray(this.getEncode(), this.encodeSupportArray) != -1;
		},

		getConditions: function () {

		},

		isValid: function (callback) {
			return this.instance.isValid(callback || function () {

			});
		},

		/**
		 * 将表单格式化成键值对形式
		 * @return {Object} 键值对的对象
		 */
		getValue: function () {
			var me = this;
			var needEncode = this.needEncode();
			var encoder = function (name, val) {
					return me.encodeSupport[name]["encode"](val);
				},
				encode = function (val) {
					return needEncode ? encoder(me.getEncode(), val) : val;
				};
			var array = $(this.instance).serializeArray();
			var result = {};
			$.each(array, function (i, item) {
				var name = item.name;
				if (!result[name]) { //如果是单个值，直接赋值
					result[name] = encode(item.value);
				} else { //多值使用数组
					if (!$.isArray(result[name])) {
						result[name] = [result[name]];
					}
					result[name].push(encode(item.value));
				}
			});

			$.each($(this.instance).find("[fb-ui]"), function (i, comp) {
				var $comp = $(comp).data("instance");
				if ($comp) {
					var name = $comp.getInstanceId();
					result[name] =
						encode($comp.getValue() == ""
							? me.getNullValue()
							: $comp.getValue());
				}
			});

			$.each(result, function (k, v) {
				if ($.isArray(v)) {
					result[k] = v.join(",");
				}
			});

			return result;
		},
		/**
		 * 设置表单的值
		 * @param {Object} obj  键值对
		 */
		setValue: function (obj) {
			var me = this;
			var needEncode = this.needEncode();
			var decoder = function (name, val) {
					return me.encodeSupport[name]["decode"](val);
				},
				decode = function (val) {
					return needEncode ? decoder(me.getEncode(), val) : val;
				};
			for (var name in obj) {
				if (obj.hasOwnProperty(name)) {
					me.setField(name, decode(obj[name]), obj);
				}
			}
		},
		/**
		 * 清空表单
		 */
		clear: function () {
			var form = this.instance;
			var elements = $.makeArray(form.get(0).elements);

			$.each(elements, function (i, element) {
				var $element = $(element);
				if (element.type === 'checkbox' || element.type === 'radio') {
					$element.prop('checked', false);
				}
				$element.change();
			});

			$.each($(form).find("[fb-ui]"), function (i, n) {
				var instance = $(n).data("instance");
				instance && instance.clear && instance.clear();
			});

		},
		/**
		 * 设置表单字段
		 * @param {string} fieldName 字段名
		 * @param {string} value 字段值
		 */
		setField: function (fieldName, value, obj) {
			var me = this;
			var form = this.instance;
			var fields = form.get(0).elements[fieldName];
			$.each($(form).find("[fb-ui]"), function (i, n) {
				var instance = $(this).data("instance");
				if (instance && instance.getInstanceId() == fieldName) {
					fields = this;
					return false;
				}
			});
			if (fields && fields.type) {
				me._setFieldValue(fields, value, obj);
			} else if ($.isArray(fields) || (fields && fields.length)) {
				$.each(fields, function (i, field) {
					me._setFieldValue(field, value, obj);
				});
			}
		},
		/**
		 * 设置字段的值
		 * @param field
		 * @param value
		 * @private
		 */
		_setFieldValue: function (field, value, obj) {
			var $field = $(field);
			var xtype = $field.data("xtype");
			var instance = $field.data("instance");

			if (field.type === 'checkbox') {
				value = value.split(",");
				if (field.value == '' + value || ($.isArray(value) && firebird.array.indexOf(value, field.value) !== -1)) {
					$field.prop('checked', true);
				} else {
					$field.prop('checked', false);
				}
			} else if (field.type === 'radio') {
				if (field.value == '' + value) {
					$field.prop('checked', true);
				} else {
					$field.prop('checked', false);
				}
			} else if (xtype && xtype == "editor") {
				var decode = $field.attr("fb-decode");
				if (decode && decode.toString() == "true") {
					value = firebird.decodeHTML(value);
				}
				instance && instance.setValue && instance.setValue(value);
			} else if (xtype
				&& (xtype == "selecter"
					|| xtype == "multiselecter"
					|| xtype == "treeselecter"
					|| xtype == "singleselecter"
					|| xtype == "suggestselecter"
					|| xtype == "checkgroup")) {

				instance.getAsyncData(function () {
					instance && instance.setValue && instance.setValue(value);
				});

			} else if (xtype && xtype == "datepicker") {
				instance.setValue(value);
			} else if (xtype && (xtype == "attachment" || xtype == "attachment")) {
				instance && instance.setValue && instance.setValue(value);
			} else if (xtype && (xtype == "textfield" || xtype == "textarea")) {
				instance && instance.setValue && instance.setValue(value);
			} else {
				$field.val(value);
			}
		},
		/**
		 * 获取表单字段值
		 * @param {string} fieldName 字段名
		 * @return {String}   字段值
		 */
		getField: function (fieldName) {
			return this.serializeToObject()[fieldName];
		}
	});

	module.exports = Firebird.ui.FormHelper;

});